/*
 * CloudBank Mobile Knowledge Sharing for Language Learners
 * Supported by the JISC Rapid Innovation Programme #jiscri
 *
 * Copyright (C) 2010 University of Brighton
 *
 * Licensed under the GNU General Public License v3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.gnu.org/licenses/gpl.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package uk.ac.brighton.itrg.cloudbank;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.SpannableString;
import android.text.method.LinkMovementMethod;
import android.text.util.Linkify;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.ToggleButton;
import android.widget.AdapterView.OnItemClickListener;


public class ActivityBrowse extends ListActivity implements OnClickListener, OnItemClickListener, OnTouchListener
{
	private static final String TAG = ActivityBrowse.class.getSimpleName();
	
	private ToggleButton tglMY, tglALL, tglDATE, tglABC;
	
	private String mSearch;
	private boolean mFlagRemote, mFlagSortAbc, mFlagForceRefresh;
	
	private TextView txtSearch;
	private Cursor mCursor;
	
	private ProgressDialog mProgress;
	private Handler mHandler; 
	
	
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
        Logger.log(TAG + ".onCreate()");
        try
        {
        	setContentView(R.layout.browse);

	        // register listeners
        	tglMY = (ToggleButton) findViewById(R.id.tglMY);
        	tglALL = (ToggleButton) findViewById(R.id.tglALL);
        	tglDATE = (ToggleButton) findViewById(R.id.tglDATE);
        	tglABC = (ToggleButton) findViewById(R.id.tglABC);
        	tglMY.setOnClickListener(this);
        	tglALL.setOnClickListener(this);
        	tglDATE.setOnClickListener(this);
        	tglABC.setOnClickListener(this);
        	
	        findViewById(R.id.btnSearch).setOnClickListener(this);
	        findViewById(R.id.btnReload).setOnClickListener(this);
	        findViewById(R.id.btnAdd).setOnClickListener(this);
	        getListView().setOnItemClickListener(this);
	        
	        txtSearch = (TextView) findViewById(R.id.txtSearch);
	        txtSearch.setOnTouchListener(this);

            mFlagForceRefresh = false;

	        if (savedInstanceState != null) 
	        {
	        	String s = savedInstanceState.getString("mSearch");
	        	mSearch = ((s == null) || s.equals("null")) ? null : s;
	        	
	        	s = savedInstanceState.getString("mFlagRemote");
	        	mFlagRemote = Boolean.parseBoolean(s);
	        	
	        	s = savedInstanceState.getString("mFlagSortAbc");
	        	mFlagSortAbc = Boolean.parseBoolean(s);
	        }
	        else
	        {
	            mSearch = null;
	            mFlagRemote = false;
	            mFlagSortAbc = false;
	        }
        }
        catch(Exception e)
        {
        	Logger.log(e);
        }
	}
	

	// ------------------------------------------
    // app becomes visible
	// ------------------------------------------
	public void onStart()
	{
		super.onStart();
        Logger.log(TAG + ".onStart()");
        updateContent();
    }

	// ------------------------------------------
    // app becomes invisible
	// ------------------------------------------
	public void onStop()
	{
		super.onStop();
        Logger.log(TAG + ".onStop()");
		mCursor.close();
	}

	// ------------------------------------------
	// Save away the original text, so we still have it 
    // if the activity needs to be killed while paused.
	// ------------------------------------------
    protected void onSaveInstanceState(Bundle outState) 
    {
    	Logger.log(TAG + ".onSaveInstanceState()");

        outState.putString("mSearch", mSearch);
        outState.putString("mFlagRemote", Boolean.toString(mFlagRemote));
        outState.putString("mFlagSortAbc", Boolean.toString(mFlagSortAbc));
    }

	
	// ------------------------------------------
    // update item list
	// ------------------------------------------	
	private void updateContent()
	{
		if(mFlagRemote)
		{
			// ------------------------------------------
		    // asynchronous:
			// 1 - show ProgressDialog
			// 2 - set up handler to update UI with new data
			// 3 - start thread to retrieve new data
			// ------------------------------------------	

			mProgress = ProgressDialog.show(this, null, "loading, please wait...", true, false);

			mHandler = new Handler() // never update UI on asynchronous thread!
			{
		        public void handleMessage(Message msg) 
		        {
		        	mProgress.dismiss();
		        	if(DB.errorState()) 
		        	{
		            	new AlertDialog.Builder(ActivityBrowse.this)
		                .setMessage(DB.getLastErrorMessage(ActivityBrowse.this))
		                .setPositiveButton("OK", new DialogInterface.OnClickListener() 
		                {
		                        public void onClick(DialogInterface dialog, int whichButton) 
		                        {
		        	            	ActivityBrowse.this.finish();
		                        } 
		                }).show();
		        	}
		        	else
		        	{
						updateUI();
		        	}
		        }
		    };
		    
			new Thread(new Runnable() // asynchronously get remote cursor
			{
				public void run()
				{
					String intag = (CB.INCLUDE_TAGS.length() > 0) ? CB.INCLUDE_TAGS : null;
					String extag = (CB.EXCLUDE_TAGS.length() > 0) ? CB.EXCLUDE_TAGS : null;
					String sort = mFlagSortAbc ? "item" : null;
					mCursor = DB.getItemList(intag, extag, mSearch, sort, mFlagForceRefresh);
					mFlagForceRefresh = false;
					mHandler.sendEmptyMessage(0);
				}
			}).start();
		}
		else
		{
			String sort = mFlagSortAbc ? "item" : null;
	    	mCursor = DB.getLocalItemList(mSearch, sort, this);
	    	updateUI();
		}
	}
	
	
	// ------------------------------------------
	// Update UI with current values 
	// ------------------------------------------
    private void updateUI() 
    {
		// bind cursor to list
    	SimpleCursorAdapter a = new SimpleCursorAdapter(this, R.layout.item, mCursor, 
    			                                        mCursor.getColumnNames(), 
    													new int[] {R.id.item_id, R.id.item_item});
    	setListAdapter(a);
    	
    	// select first item in list
		ListView v = getListView();
		v.setSelection(0);
		v.requestFocus();
		
		// update search string
    	if(mSearch == null) txtSearch.setText(R.string.search_prompt);
    	else                txtSearch.setText(mSearch);	    	

        tglMY.setChecked(!mFlagRemote);
        tglALL.setChecked(mFlagRemote);
        tglDATE.setChecked(!mFlagSortAbc);
        tglABC.setChecked(mFlagSortAbc);
    }

    
	// ------------------------------------------
    // interface OnClickListener
	// ------------------------------------------
    public void onClick(View v) 
    {
        Logger.log(TAG + ".onClick()");
        switch(v.getId())
    	{
    	case R.id.btnSearch: 
			
            try 
            {
            	String s = txtSearch.getText().toString().trim();
            	
            	if(s.length() == 0
            	|| s.equals(getResources().getString(R.string.search_prompt)))
            	{
        	    	new AlertDialog.Builder(ActivityBrowse.this)
        	        .setMessage("Please enter a search term!")
        	        .setPositiveButton("OK", null)
        	        .show();
            	}
            	else
            	{
                	// hide keyboard
                	InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                	imm.hideSoftInputFromWindow(txtSearch.getWindowToken(), 0);

                	mSearch = s;
                	Logger.log("mSearch", mSearch);

                	updateContent();
            	}
            } 
            catch (Exception e) 
            {
                Logger.log(e);
            }
    		break;
    		
    	case R.id.btnReload: 

        	mSearch = null;
        	mFlagForceRefresh = true;
         	updateContent();
    		break;
    		
    	case R.id.btnAdd: 
			
        	Intent edit = new Intent(this, ActivityEdit.class);
        	startActivityForResult(edit, R.id.btnAdd);
    		break;
    		
    	case R.id.tglMY: 

         	mFlagRemote = false;
         	updateContent();
    		break;
    		
    	case R.id.tglALL: 
 
         	mFlagRemote = true;
         	updateContent();
    		break;
    		
    	case R.id.tglDATE: 

         	mFlagSortAbc = false;
         	updateContent();
    		break;
    		
    	case R.id.tglABC: 

         	mFlagSortAbc = true;
         	updateContent();
    		break;
    	}
    }


    // -------------------------------------------------
    // user clicks / taps on an entry in the list
    // -------------------------------------------------
	public void onItemClick(AdapterView<?> parent, View view, int position, long id)
	{
        Logger.log(TAG + ".onItemClick()");
		try
		{
			Intent detail = new Intent(this, ActivityDetail.class);
			detail.putExtra("Item._id", id);
			startActivity(detail);
        }
        catch(Exception e)
        {
        	Logger.log(e);
        }
	}

	

	
	

	// -------------------------------------------------------------
    // reset values when we come back from Detail or Edit activities 
	// -------------------------------------------------------------
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
         super.onActivityResult(requestCode, resultCode, data);

         Logger.log(TAG + ".onActivityResult()");
         Logger.log("requestCode", requestCode);
         Logger.log("resultCode", resultCode);
         
         switch(requestCode)
         {
         
         case R.id.btnAdd:  // we come back from Edit / Add

        	 if (resultCode == Activity.RESULT_OK) 
        	 {
        		 Logger.log("Back from Edit");
      			 // show MyWords without filters, last added top of list 
        		 mSearch = null;
        		 mFlagRemote = false;
        		 mFlagSortAbc = false;        		 
        	 }
        	 break;
         }
    }

    
    
    
	// --------------------------------------------------------
    // select or reset search text user taps on the search box
	// --------------------------------------------------------
	public boolean onTouch(View v, MotionEvent event)
	{
        Logger.log(TAG + ".onTouch()");

		if(event.getAction() == MotionEvent.ACTION_DOWN)
		{
			Logger.log("MotionEvent.ACTION_DOWN");
			
			try
			{
				EditText edt = (EditText)v;
				String txt = edt.getText().toString();

				if(txt.equals(getResources().getString(R.string.search_prompt)))
				{
					edt.setText("");
				}
				else
				{
					edt.setSelection(0, edt.getText().length());
				}
			}
			catch(Exception e)
			{
				Logger.log(e);
			}
		}
		return false;
	}
    
	

	
	

	// ------------------------------------------
    // mww 06/2010 v.4 menu and preferences
    // create and listen to menu
	// ------------------------------------------
	public boolean onCreateOptionsMenu(Menu menu)
	{
		super.onCreateOptionsMenu(menu);
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.browse, menu);	
		return true;
	}
	public boolean onPrepareOptionsMenu(Menu menu)
	{
		if(mFlagRemote)	
		{
			 menu.findItem(R.id.mneClear).setVisible(false).setEnabled(false); 
		}
		else
		{
			 menu.findItem(R.id.mneClear).setVisible(true).setEnabled(true); 
		}
		return true;
	}
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch(item.getItemId())
		{
		case R.id.mneClear:
	    	new AlertDialog.Builder(ActivityBrowse.this)
	        .setMessage("Clear all entries from your \nMy Words list.\n\nAre you sure?\n ")
	        .setPositiveButton("Yes", new DialogInterface.OnClickListener() 
	        {
	                public void onClick(DialogInterface dialog, int whichButton) 
	                {
	                	DB.zapDatabase(ActivityBrowse.this);
	                 	updateContent();
	                } 
	        })
	        .setNegativeButton("No", null).show();
			 return true;

		case R.id.mneSettings:
			 startActivity(new Intent(this, ActivitySettings.class));
			 return true;

		case R.id.mneAbout:
			 final TextView message = new TextView(this);
		     final SpannableString s = new SpannableString(getText(R.string.about_text));
			 Linkify.addLinks(s, Linkify.WEB_URLS);
			 message.setText(s);
			 message.setMovementMethod(LinkMovementMethod.getInstance());

			 new AlertDialog.Builder(this)
			 .setTitle(R.string.about_title)
			 .setIcon(R.drawable.icon)
			 .setPositiveButton("OK", null)
			 .setView(message)
			 .show();
        	 
			 return true;

		case R.id.mneHelp:
			 startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(CB.getHelpPage(this)))); 
			 return true;
		}
		return false;
	}
	
}
